package priv.pfz.raft.peer.model;

import com.google.common.collect.Lists;
import lombok.Getter;
import lombok.Setter;
import priv.pfz.raft.common.ToString;

import java.util.List;

/**
 * @author pengfangzhou
 * @date 2022/2/5 21:49
 */
@Getter
@Setter
public class Logs extends ToString {

    private LogKey commitLogKey = LogKey.DEFAULT;
    private List<LogEntry> logs = Lists.newArrayList();

    public void addLog(LogEntry logEntry) {
        logs.add(logEntry);
    }

    public boolean isEmpty() {
        return logs.isEmpty();
    }

    public LogKey getLastLogKey() {
        return logs.isEmpty() ? LogKey.DEFAULT : logs.get(logs.size() - 1).getLogKey();
    }

    public LogEntry getPrevLog(int term, int index) {
        for (int i = 1; i < logs.size(); i++) {
            LogEntry logEntry = logs.get(i);
            if (logEntry.getTerm() == term && logEntry.getIndex() == index) {
                return logs.get(i - 1);
            }
        }
        return null;
    }

    public LogEntry getNextLog(int term, int index) {
        if (term == 0 && index == 0 && !logs.isEmpty()) {
            return logs.get(0);
        }
        for (int i = 0; i < logs.size() - 1; i++) {
            LogEntry logEntry = logs.get(i);
            if (logEntry.getTerm() == term && logEntry.getIndex() == index) {
                return logs.get(i + 1);
            }
        }
        return null;
    }

    public LogEntry getNextLog(LogKey logKey) {
        if (logKey.compareTo(LogKey.DEFAULT) == 0 && !logs.isEmpty()) {
            return logs.get(0);
        }
        for (int i = 0; i < logs.size() - 1; i++) {
            LogEntry logEntry = logs.get(i);
            if (logEntry.getLogKey().compareTo(logKey) == 0) {
                return logs.get(i + 1);
            }
        }
        return null;
    }

    public LogEntry getLog(int term, int index) {
        for (int i = 0; i < logs.size(); i++) {
            LogEntry logEntry = logs.get(i);
            if (logEntry.getTerm() == term && logEntry.getIndex() == index) {
                return logEntry;
            }
        }
        return null;
    }

    public LogEntry getLog(LogKey logKey) {
        for (int i = 0; i < logs.size(); i++) {
            LogEntry logEntry = logs.get(i);
            if (logEntry.getLogKey().compareTo(logKey) == 0) {
                return logEntry;
            }
        }
        return null;
    }
}
